
#include "lib_jpeg.h"

#define  MAX_IMAGE_W      	  (8192)
#define  MAX_IMAGE_H     	  (8192)
#define  MAX_IMAGE_BPP        (3)

//*******************************************************************************

#define CODEC_ALIGN(x, a)   (((x)+(a)-1)&~((a)-1))
//*******************************************************************************

static  char * image_edp_src_buff  	  = NULL;
static  char * image_edp_dst_buff     = NULL;
//*******************************************************************************
int is_jpeg_file_t(char *filename,jpeg_file_t *pfd)
{
	int ret;
	uint32_t word;

    pfd->cinfo.err = jpeg_std_error(&pfd->jerr);
	//创建一个jpeg_compress_struct结构体
    jpeg_create_decompress(&pfd->cinfo);
	
	//指定jpeg解压的源文件
    jpeg_stdio_src(&pfd->cinfo, pfd->fp);
	
	//解析jpeg文件，解析完成后可获得图像的格式
    ret = jpeg_read_header(&pfd->cinfo, TRUE);
	if(ret < 0){
		log_e("file is not jpg ...\n");
		return -1;
	}

	return 0;
}


void free_jpeg(jpeg_file_t *jf)
{
	if(jf->buffer)
	{
		free(jf->buffer);
	}

	jf->buffer = NULL;
}



int decode_jpeg(char *filename,jpeg_file_t *jf)
{
	int ret;
	uint32_t word;
	unsigned char *buf_cpy;
	//临时变量行buffer
	uint8_t *pucbuffer;
	
	//放大倍率
	jf->cinfo.scale_num = 1;//2
	//缩小倍率
	jf->cinfo.scale_denom = 1;

	//jf->cinfo.out_color_space = JCS_RGB;

	//对cinfo所指定的源文件进行解压，并将解压后的数据存到cinfo结构体的成员变量中。
    jpeg_start_decompress(&jf->cinfo);
	//获取图片基本信息
    jf->row_size = jf->cinfo.output_width * jf->cinfo.output_components;
    jf->width = jf->cinfo.output_width;
    jf->height = jf->cinfo.output_height;
	jf->Bpp = jf->cinfo.output_components;
    jf->size = jf->row_size * jf->cinfo.output_height;
	
	//分配内存空间 
	pucbuffer = malloc(jf->row_size);
    jf->buffer = malloc(jf->size);

#if 0

	log_i("jpeg_color_space=%d\n",jf->cinfo.jpeg_color_space);

    printf("size: %d w: %d h: %d row_size: %d ,Bpp: %d\n",
			jf->size,jf->width,jf->height,jf->row_size,jf->Bpp);
#endif
			
	//缓冲指针指向buffer		
	buf_cpy = jf->buffer;

    while (jf->cinfo.output_scanline < jf->cinfo.output_height){
        //可以读取RGB数据到buffer中，参数3能指定读取多少行
		jpeg_read_scanlines(&jf->cinfo, &pucbuffer, 1);
        //复制到内存
		memcpy(buf_cpy , pucbuffer, jf->row_size);
		buf_cpy = buf_cpy + jf->row_size;
    }

	// 完成解码
	jpeg_finish_decompress(&jf->cinfo);
	free(pucbuffer);
	//释放结构体
    jpeg_destroy_decompress(&jf->cinfo);

	return 0;
}

int decode_jpeg_and_show(char *filename)
{
	int ret;

	int i = 0;
	int j = 0;
	
	int dst_w = 0;
	int dst_h = 0;

	int src_w = 0;
	int src_h = 0;

	int lcd_w = 0;
	int lcd_h = 0;

	int bpp   = 0;
		
	jpeg_file_t jf;

	//**************************************************

	jf.fp= fopen(filename, "rb");
	if (jf.fp== NULL) {
		log_e("can not open file,%s\n",filename);
		return -1;
	}
	
	memset(jf.filename,0,sizeof(jf.filename));
	memcpy(jf.filename,filename,strlen(filename));

	ret =is_jpeg_file_t(filename,&jf);
	if(ret < 0 ){
		log_e("not jpeg file");
    	fclose(jf.fp);
		return -1;
	}

	ret = decode_jpeg(filename,&jf);
	if(ret < 0 ){
		log_e("decode jpeg wrong\n");
		fclose(jf.fp);
		return -1;
	}
	//***********************************************************************************************
	log_n("jf.width =%d\n",jf.width);
	log_n("jf.height=%d\n",jf.height);
	log_n("jf.Bpp   =%d\n",jf.Bpp);
	//***********************************************************************************************
	src_w  = CODEC_ALIGN(jf.width, 4);
    src_h  = CODEC_ALIGN(jf.height, 4);

	log_n("src_w =%d\n",src_w);
	log_n("src_h =%d\n",src_h);
	//***********************************************************************************************
	
	memset(image_edp_src_buff,0,MAX_IMAGE_W*MAX_IMAGE_H*MAX_IMAGE_BPP);
	memset(image_edp_dst_buff,0,MAX_IMAGE_W*MAX_IMAGE_H*MAX_IMAGE_BPP);

	for(i = 0;i < jf.height;i++)
	{
		memcpy(image_edp_src_buff + i*src_w*jf.Bpp,jf.buffer + i*jf.width*jf.Bpp ,jf.width*jf.Bpp);	
	}
	//***********************************************************************************************
	if(src_w > src_h)//for edp show
	{
		lcd_w = lib_drm_get_edp_w();
		lcd_h = lib_drm_get_edp_h();		
		#if 0
		if((src_w >= lcd_w)&&(src_h >= lcd_h))
		{
			dst_w = lcd_w;
			dst_h = lcd_h;
		}
		else if((src_w >= lcd_w)&&(src_h < lcd_h))
		{	
			dst_w = (src_w*lcd_h/src_h);
			dst_h = lcd_h;
		}
		else if((src_w < lcd_w)&&(src_h >= lcd_h))
		{
			dst_w = (src_w*lcd_h)/src_h;
			dst_h = lcd_h;
		}
		else 
		{
			dst_w = src_w;
			dst_h = src_h;
		}
		#else
		
		dst_w = lcd_w;
		dst_h = lcd_h;

		#endif
		
		log_n("e_src_w =%d\n",src_w);
		log_n("e_src_h =%d\n",src_h);

		log_n("e_dst_w =%d\n",dst_w);
		log_n("e_dst_h =%d\n",dst_h);

		ret = rga_rgbdata_resize(image_edp_src_buff,src_w,src_h,jf.Bpp,
								 image_edp_dst_buff,dst_w,dst_h,jf.Bpp);

		 if(ret >= 0)
		 {
			 lib_drm_edp_show(image_edp_dst_buff,dst_w,dst_h,dst_w*dst_h*4);
		 }
	}
	else
	{
		lcd_w = lib_drm_get_hdmi_w();
		lcd_h = lib_drm_get_hdmi_h();

		#if 0
		if((src_w >= lcd_h)&&(src_h >= lcd_w))
		{
			dst_w = lcd_w;
			dst_h = lcd_h;
		}
		else if((src_w >= lcd_h)&&(src_h < lcd_w))
		{	
			dst_w = (src_w*lcd_h/src_h);
			dst_h = lcd_h;
		}
		else if((src_w < lcd_h)&&(src_h >= lcd_w))
		{
			dst_w = (src_w*lcd_h)/src_h;
			dst_h = lcd_h;
		}
		else 
		{
			dst_w = src_w;
			dst_h = src_h;
		}
		
		#else
		
		dst_w = lcd_w;
		dst_h = lcd_h;
		
		#endif
		
		log_n("h_src_w =%d\n",src_w);
		log_n("h_src_h =%d\n",src_h);

		log_n("h_dst_w =%d\n",dst_w);
		log_n("h_dst_h =%d\n",dst_h);

		ret = rga_rgbdata_resize_hdmi(image_edp_src_buff,src_w,src_h,jf.Bpp,
								      image_edp_dst_buff,dst_h,dst_w,jf.Bpp);

		if(ret >= 0)
		{
			lib_drm_hdmi_nv12_show(image_edp_dst_buff,dst_h,dst_w,dst_w*dst_h*jf.Bpp);
		}
	}
	//***********************************************************************************************
	
	fclose(jf.fp);
	free_jpeg(&jf);
	
	//***********************************************************************************************
	
	return ret;

}



int lib_jpeg_init(void)
{
	unsigned long max_address = 0xfffffffe; // 4GB

	log_n("lib jpeg init.\n");
	
	log_n("max_address=%x\n",max_address);
	//************************************************************

	//max 4G 
	image_edp_src_buff = malloc(MAX_IMAGE_W*MAX_IMAGE_H*MAX_IMAGE_BPP);	
	if((image_edp_src_buff == NULL)||(image_edp_src_buff < max_address))
	{
		exit(-1);
	}

	//************************************************************

	image_edp_dst_buff = malloc(MAX_IMAGE_W*MAX_IMAGE_H*MAX_IMAGE_BPP);
	if((image_edp_dst_buff == NULL)||(image_edp_dst_buff < max_address))
	{
		exit(-1);
	}
	//************************************************************


	return 0;
}


int lib_jpeg_deinit(void)
{
	log_i("lib jpeg exit.\n");






	return 0;
}
